package it.rap.application.logic.mappers;

import it.rap.application.logic.BusinnessLogic;
import it.rap.applications.persistence.entities.contoCorrente.ContoCorrente;
import it.rap.applications.persistence.entities.movimento.Movimento;
import it.rap.applications.persistence.entities.movimento.Saldo;

import java.math.BigDecimal;
import java.util.List;

import javax.persistence.Parameter;
import javax.persistence.Query;

public class MovimentoLogic extends BusinnessLogic {

	public MovimentoLogic() {
		super("publisher");
	}
	
	public BigDecimal getTotMovimenti(ContoCorrente cc) {
		StringBuffer q = new StringBuffer();
		q.append( " Select count(m) " );
		q.append( " from Movimento m, ContoCorrente c " );
		q.append( " WHERE m.contoCorrente.id = c.id " );
		q.append( " AND   c.state = :state " );
		Query query = enm.createQuery( q.toString() );
		if( cc.getState() != null ){
			query.setParameter("state", cc.getState() );
		} else {
			return new BigDecimal("-1");
		}
		Long result =  (Long) query.getSingleResult();
		if ( result != null ) return new BigDecimal( result );
		return new BigDecimal("0");
	}
	
	public Movimento loadMovimentoMaxDataContabile(ContoCorrente cc){
		StringBuffer q = new StringBuffer();
		q.append( " SELECT m ");
		q.append( " FROM Movimento m, ContoCorrente c " );
		q.append( " WhERE m.contoCorrente.id = c.id" );
		q.append( " AND   c.state = :state" );
		q.append( " ORDER BY m.dataContabile DESC" );
		Query query = enm.createQuery( q.toString() );
		if( cc.getState() != null ){
			query.setParameter("state", cc.getState() );
		} else {
			return null;
		}
		query.setMaxResults(1);	
		
		List<Movimento> mList = query.getResultList();
		if ( mList != null && mList.size() > 0 ){
			return mList.get(0);
		}
		return null;
	}
	
	public Saldo calcolaSaldo(ContoCorrente cc){
		//Query query = enm.createNamedQuery("calcoloSaldo");
		//Object s = query.getSingleResult();
		StringBuffer q = new StringBuffer();
		q.append( " SELECT ( IFNULL( SUM(accredito), 0 ) - IFNULL( SUM(addebito), 0) ) as saldo, IFNULL( SUM(accredito), 0 ) as totaleAccrediti, IFNULL( SUM(addebito), 0) as totaleAddebiti " );
		q.append( " FROM Movimento m, ContoCorrente c " );
		q.append( " WHERE m.contoCorrente_id = c.id " );
		q.append( " AND   c.state = ? " );
		Query query = enm.createNativeQuery( q.toString() );
		if( cc.getState() != null ){
			query.setParameter(1, cc.getState());
		} else {
			return null;
		}
		List<Object[]> results = query.getResultList();
		Saldo s = new Saldo();
		s.setSaldo( ((Double) results.get(0)[0]).floatValue() );
		s.setTotaleAccrediti( ((Double) results.get(0)[1]).floatValue() );
		s.setTotaleAddebiti( ((Double) results.get(0)[2]).floatValue() );
		return (Saldo)s;
	}

	public int esisteMovimento(Movimento m) {
		StringBuffer q = new StringBuffer();
		q.append( " SELECT COUNT(m) ");
		q.append( " FROM  Movimento m, ContoCorrente c" );
		q.append( " WHERE m.contoCorrente.id = c.id ");
		q.append( " AND c.state = :state " );
		if( m.getDataContabile() != null ){
			q.append( " AND m.dataContabile = :dataContabile ");
		}
		if ( m.getDataValuta() != null ){
			q.append( " AND m.dataValuta = :dataValuta ");
		}
		if ( m.getAddebito() != null ){
			q.append( " AND	CAST( m.addebito AS DECIMAL )   = CAST( :addebito AS DECIMAL ) ");
		}
		if ( m.getAccredito() != null ){
			q.append( " AND	CAST( m.accredito AS DECIMAL ) = CAST( :accredito AS DECIMAL ) ");
		}
		if( m.getDescrizione() != null ){
			q.append( " AND m.descrizione = :descrizione ");
		}
		if( m.getDescrizioneCompleta() != null ){
			q.append( " AND m.descrizioneCompleta = :descrizioneCompleta ");
		}
		Query query = enm.createQuery( q.toString() );
		if( m.getDataContabile() != null ){
			query.setParameter("dataContabile", m.getDataContabile());
		}
		if ( m.getDataValuta() != null ){
			query.setParameter("dataValuta", m.getDataValuta());
		}
		if ( m.getAddebito() != null ){
			query.setParameter("addebito", m.getAddebito());
		}
		if ( m.getAccredito() != null ){
			query.setParameter("accredito", m.getAccredito());
		}
		if ( m.getDescrizione() != null ){
			query.setParameter("descrizione", m.getDescrizione());
		}
		if ( m.getDescrizioneCompleta() != null ){
			query.setParameter("descrizioneCompleta", m.getDescrizioneCompleta());
		}
		if( m.getContoCorrente().getState() != null ){
			query.setParameter("state",  m.getContoCorrente().getState() );
		} else {
			return -1;
		}
		Long  o = (Long)query.getSingleResult();
		return o.intValue();
	}

	public void persist(Movimento m) {
		enm.persist(m); 
	}

	public List<Movimento> selectAll(ContoCorrente cc, Integer currentDataOffset,	Integer currentDataLimit) {
		StringBuffer q = new StringBuffer();
		q.append( " SELECT m ");
		q.append( " FROM  Movimento m, ContoCorrente c" );
		q.append( " WHERE m.contoCorrente.id = c.id ");
		q.append( " AND c.state = :state " );
		q.append( " ORDER BY m.dataContabile DESC" );
		Query query = enm.createQuery( q.toString() );
		if( cc.getState() != null ){
			query.setParameter("state", cc.getState() );
		} else {
			return null;
		}
		query.setFirstResult( currentDataOffset ).setMaxResults( currentDataLimit );
		List<Movimento> mList = (List<Movimento>)query.getResultList();
		return mList;
	}

}
